package itsm.isperp.module.service.knowledge;

import itsm.isperp.framework.data.dialect.DialectFactory;
import itsm.isperp.framework.data.domain.FilterRule;
import itsm.isperp.framework.data.domain.PageResponse;
import itsm.isperp.framework.service.BaseService;
import itsm.isperp.framework.web.request.JqGridFilterRule;
import itsm.isperp.framework.web.request.JqGridFilterRuleOp;
import itsm.isperp.framework.web.request.JqGridRequest;
import itsm.isperp.framework.web.response.ResultMessage;
import itsm.isperp.module.dto.solr.SolrKngKnowledgeDTO;
import itsm.isperp.module.entity.knowledge.KngKnowledgeItem;
import itsm.isperp.module.repository.knowledge.KngKnowledgeItemMapper;
import itsm.isperp.module.repository.solr.SolrKngKnowledgeItemRepository;
import itsm.isperp.module.service.app.AppDictService;
import itsm.isperp.module.utils.SolrUtils;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jdbc.support.DatabaseType;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.HighlightQuery;
import org.springframework.data.solr.core.query.SimpleHighlightQuery;
import org.springframework.data.solr.core.query.SimpleStringCriteria;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class KngKnowledgeItemService extends BaseService<KngKnowledgeItem> {

	@Autowired
	protected KngKnowledgeItemMapper kngKnowledgeItemMapper;

	@Autowired
	protected AppDictService appDictService;

	@Autowired
	protected SolrKngKnowledgeItemRepository solarKngKnowledgeItemRepository;

	@Autowired
	protected JdbcTemplate jdbcTemplate;

	@Override
	public KngKnowledgeItemMapper getRepository() {
		return this.kngKnowledgeItemMapper;
	}

	@Override
	public int saveOrUpdateAndSpecific(KngKnowledgeItem entity,
			HttpServletRequest req, String... otherFields) {

		int i = super.saveOrUpdateAndSpecific(entity, req, otherFields);
		String dStatus = appDictService.findLastOneByType(
				"KNOWLEDGE_ITEM_STATUS").getName();
		try {

			String status = jdbcTemplate.queryForObject(
					"SELECT status FROM kng_knowledge_item WHERE id=?",
					String.class, entity.getId());

			if (dStatus.equals(status)) {
				saveIndex(entity.getId());
				SolrUtils.rebuildKnowledgeFileIndex(entity.getId());
			}

		} catch (Exception e) {

		}
		return i;
	}

	public ResultMessage delete(String id) {
		ResultMessage rs = super.delete(id);

		this.solarKngKnowledgeItemRepository.delete(id);

		try {
			List<String> ids = jdbcTemplate.queryForList(
					"SELECT id FROM app_upload_file WHERE source_id=?",
					String.class, id);
			for (String fid : ids) {
				this.solarKngKnowledgeItemRepository.delete(fid);
			}

		} catch (Exception e) {

		}
		return rs;
	}

	public void saveIndex(String id) throws DocumentException {
		this.solarKngKnowledgeItemRepository.saveIndex(id);

	}

	public void deleteIndex(String id) {
		this.solarKngKnowledgeItemRepository.delete(id);
	}

	public SolrKngKnowledgeDTO findOneDto(String id) {
		return this.solarKngKnowledgeItemRepository.findOne(id);
	}

	/*
	 * 根据关键字搜索知识库（支持全文检索）
	 * 
	 * @para keyword 关键字
	 * 
	 * @advanceCondition 高级查询条件，
	 */
	 public Page<SolrKngKnowledgeDTO> searchByKeyword(String keyword,
	      Pageable pageable, Criteria[] advanceCondition, String accessRight) {

	    if (StringUtils.isEmpty(keyword)) {
	      return null;
	    }

	    keyword = ClientUtils.escapeQueryChars(keyword);

	    HighlightQuery query = new SimpleHighlightQuery(
	        new Criteria("classType").is("SolrKngKnowledgeDTO"));
	    StringBuilder stringBuilder = new StringBuilder();

	    stringBuilder.append("status:");
	    stringBuilder.append(appDictService.findLastOneByType(
	        "KNOWLEDGE_ITEM_STATUS").getName());
	    stringBuilder.append(" AND ( title:");
	    stringBuilder.append(keyword);
	    stringBuilder.append(" OR categoryName:");
	    stringBuilder.append(keyword);
	    stringBuilder.append(" OR contents:");
	    stringBuilder.append(keyword);
	    stringBuilder.append(" OR keyword:");
	    stringBuilder.append(keyword);
	    stringBuilder.append(")");
	    if (StringUtils.isNotEmpty(accessRight))
	      stringBuilder.append(" AND (accessRight:"+accessRight+")");
	    String queryStr = stringBuilder.toString();

	    SimpleStringCriteria c = new SimpleStringCriteria(queryStr);
	    if (advanceCondition != null) {
	      for (Criteria cc : advanceCondition) {
	        query.addCriteria(cc);
	      }
	    }

	    query.addCriteria(c);
	    query.setPageRequest(pageable);

	    Page<SolrKngKnowledgeDTO> p = solarKngKnowledgeItemRepository
	        .searchByKeyword(query);

	    if (p.getTotalElements() > 0) {
	      String data = "";

	      JqGridRequest req = new JqGridRequest();

	      for (SolrKngKnowledgeDTO d : p.getContent()) {
	        data += ",'" + d.getId() + "'";
	      }

	      req.isPageable(false);
	      req.setSelectColumns("id", "readTimes", "commentary_times");
	      req.addFilterRule("id", JqGridFilterRuleOp.in, data.substring(1));
	      List<KngKnowledgeItem> kngs = this.findAll(req);

	      for (SolrKngKnowledgeDTO d : p.getContent()) {

	        FIND_ITEM: for (KngKnowledgeItem k : kngs) {
	          if (k.getId().equals(d.getId())) {
	            d.setReadTimes(k.getReadTimes());
	            d.setCommentaryTimes(k.getCommentaryTimes());
	            break FIND_ITEM;
	          }
	        }

	      }

	    }

	    return p;
	  }

	/**
	 * 获取热门知识(前10条) 热门知识根据两个条件来定义： 1、热度：热度=阅读数+评论数×10 2、时间：最近3个月
	 * 
	 * @return List<Map>
	 */
	public List<Map<String, Object>> getTop10Item() {
		return kngKnowledgeItemMapper.getTop10Item();
	}
	
	public List<Map<String, Object>> getTop10ItemPublic() {
		return kngKnowledgeItemMapper.getTop10ItemPublic();
	}

	/**
	 * 获取最新知识(前10条)
	 * 
	 * @return List<Map>
	 */
	public List<KngKnowledgeItem> getNewTop10Item(int num,String searchSql) {

		JqGridRequest req = new JqGridRequest();
		req.isPageable(false);
		req.setRows(num);
		req.addFilterRule("status", JqGridFilterRuleOp.eq, appDictService
				.findLastOneByType("KNOWLEDGE_ITEM_STATUS").getName());
		req.setSort("publish_date", Direction.DESC);
		req.setSearchString(searchSql);

		String contentsSql = null;
		if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
			contentsSql = "LEFT(title," + 26 + ") AS title";
		} else {
			contentsSql = "to_char(SUBSTR(title,0," + 26 + ")) AS title";
		}

		req.setSelectColumns("id", contentsSql,"publish_date");

		return kngKnowledgeItemMapper.findAllByRequest(req);
	}

	/**
	 * 获取知识分类统计
	 * 
	 * @return
	 */
	public List<Map<String, Object>> getCategoryCount() {
		return kngKnowledgeItemMapper.getCategoryCount();
	}

	public void increaseReadTimes(String id) {

		jdbcTemplate
				.update("UPDATE kng_knowledge_item SET read_times=read_times+1  WHERE id=?",
						id);
	}

	public PageResponse<SolrKngKnowledgeDTO> findAllPublishedDetailByRequest(
			JqGridRequest request, int contentsLength) {
		String contentsSql = null;
		if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
			contentsSql = "LEFT(contents," + contentsLength + ") AS contents";
		} else {
			contentsSql = "to_char(SUBSTR(contents,0," + contentsLength
					+ ")) AS contents";
		}
		return kngKnowledgeItemMapper.findAllPublishedDetailByRequest(request,
				contentsSql).toPage();
	}

	public PageResponse<SolrKngKnowledgeDTO> findAllPublishedDetailByRequest(
			JqGridRequest request) {
		return findAllPublishedDetailByRequest(request, 200);
	}

	public List<Map<String, Object>> findKnowLedgeFile(String sourceId) {

		String sql = null;
		if (StringUtils.isEmpty(sourceId)) {
			sql = "SELECT a.*,kc.id AS category_id,kc.treenode_path AS category_path,kc.treenode_name_path AS category_name,k.status FROM   app_upload_file a  "
					+ " INNER JOIN kng_knowledge_item k"
					+ "  ON a.source_id=k.id "
					+ " INNER JOIN kng_knowledge_category kc "
					+ " ON k.kng_knowledge_category_id=kc.id"
					+ " WHERE   k.status='"
					+ appDictService.findLastOneByType("KNOWLEDGE_ITEM_STATUS")
							.getName() + "' ";
		} else {
			sql = "SELECT a.*,kc.id AS category_id,kc.treenode_path AS category_path,kc.treenode_name_path AS category_name,k.status FROM   app_upload_file a  "
					+ " INNER JOIN kng_knowledge_item k"
					+ "  ON a.source_id=k.id "
					+ " INNER JOIN kng_knowledge_category kc "
					+ " ON k.kng_knowledge_category_id=kc.id WHERE a.source_id='"
					+ sourceId + "'";
		}

		return jdbcTemplate.queryForList(sql);
	}
}